﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;

class Building; // 声明类 

// 3. 一个类的成员函数作为另一个类的友元函数 
class GoodF3 {
public:
	// 在类的内部声明成员函数 
	void func(Building &bd);
	/*void func(Building &bd) {
		cout << "访问Building的：" << bd.keting << endl;
		cout << "访问Building的：" << bd.woshi << endl;
	}*/
};

class Building {
	// 声明GoodF这个类为Building的友元类，则GoodF中的函数就可以访问Building的私有成员了 
	friend class GoodF;
	friend class GoodF2; 
	// 声明GoodF3的成员函数func为Building类的友元函数 
	// 此行中，编译器到此只知道类GoodF3的声明，不知道类的结构，不知道有func这个函数，编译报错 
	// 解决办法是，把GoodF3::func函数从类里面拿出来，定义在外面 
	friend void GoodF3::func(Building &bd);
public:
	Building() {
		keting = "客厅";
		woshi = "卧室";
	}
public:
	string keting;
private:
	string woshi;
};

// 1. 友元类，通过参数访问其他类的私有成员  
class GoodF{
public:
	void func(Building &bd) {
		cout << "我是Building的友元类，可以访问：" << bd.woshi << endl;
	}
};

void test01() {
	Building bd;
	GoodF f;
	f.func(bd); 
}

// 2. 友元类，通过类内指针访问其他类的私有成员 
class GoodF2 {
public:
	GoodF2() {
		bd = new Building();
	}
	~GoodF2() {
		if (bd != NULL) {
			delete bd;
		}
	}
	// 拷贝构造，防止浅拷贝  
	GoodF2(const GoodF2 &f2) {
		Building *pbd = new Building;
		pbd->keting = f2.bd->keting;
		pbd->woshi = f2.bd->woshi;
		bd = pbd;
	}
	void func() {
		cout << "访问：" << bd->keting << endl;
		cout << "访问：" << bd->woshi << endl;
	}
public:
	Building *bd;
};


// 在类的外部定义成员函数 
void GoodF3::func(Building &bd) {
	cout << "访问Building的：" << bd.keting << endl;
	cout << "访问Building的：" << bd.woshi << endl;
}

void test02() {
	GoodF2 f1;
	f1.bd->keting = "第一次修改客厅";
	GoodF2 f2 = f1;
	f1.bd->keting = "第二次修改客厅";
	f2.func(); 
}


int main()
{

	// test01(); 
	test02(); 

	system("pause");
	return EXIT_SUCCESS;
}